package com.cindata

import grails.converters.JSON
import grails.transaction.Transactional
import groovy.transform.CompileStatic
import groovy.transform.TypeChecked

import java.security.MessageDigest
import java.text.SimpleDateFormat

import com.cindata.dictionary.*

@Transactional
@CompileStatic
@TypeChecked
class RiskWarningService
{
    static scope = "singleton"

    RiskWarningFlowStageService riskWarningFlowStageService
    RiskWarningFlowStageConditionService riskWarningFlowStageConditionService
    RiskWarningFlowStageEventService riskWarningFlowStageEventService
    RiskWarningFlowStageRoleService riskWarningFlowStageRoleService
    RiskWarningFlowStageNotificationService riskWarningFlowStageNotificationService

    // 初始化押品登记流程
    def initRiskWarningFlowStage(RiskWarning riskWarning, Workflow workflow = null)
    {
        if (!workflow)
        {
            def account = riskWarning?.createBy?.account
            workflow = AccountFlow.find("from AccountFlow where account.id = ? and warningType.id = ?", [account?.id, riskWarning.type?.id])?.workflow
        }

        if (workflow)
        {
            riskWarningFlowStageService.initFlowStage(riskWarning, workflow)
            riskWarningFlowStageConditionService.initFlowStageCondition(riskWarning, workflow)
            riskWarningFlowStageEventService.initFlowStageEvent(riskWarning, workflow)
            riskWarningFlowStageRoleService.initFlowStageRole(riskWarning, workflow)
            riskWarningFlowStageNotificationService.initFlowStageNotification(riskWarning, workflow)

            def flowFirstStage = WorkflowStage.find("from WorkflowStage where workflow.id = ? order by executionSequence asc", [workflow?.id])
            def riskWarningFlowStage = RiskWarningFlowStage.find("from RiskWarningFlowStage where riskWarning.id = ? and stage.id = ? order by executionSequence asc", [riskWarning?.id, flowFirstStage?.stage.id])
            if (riskWarningFlowStage)
            {
                riskWarningFlowStage.startTime = new Date()
                riskWarningFlowStage.save flush: true
                riskWarning.stage = RiskWarningStage.find("from RiskWarningStage where id = ?", [flowFirstStage?.stage?.id])
                riskWarning.isInWorkflow = true
                riskWarning.save flush: true
            }
        }
        else
        {
            println "未找到工作流，预警 ${riskWarning} 初始化失败"
        }
    }

    // 推进
    def approve(RiskWarning riskWarning)
    {
        def map = [:]


        def currentFlowStage = RiskWarningFlowStage.find("from RiskWarningFlowStage where riskWarning.id = ? and stage.id = ? order by executionSequence asc", [riskWarning?.id, riskWarning?.stage.id])

        // 事件
        riskWarningFlowStageEventService.evaluate(currentFlowStage, "negative")

        // 验证
        def verifyCondition = riskWarningFlowStageConditionService.evaluate(riskWarning)
        if (!verifyCondition['flag'])
        {
            return verifyCondition
        }

        def nextFlowStage = RiskWarningFlowStage.find("from RiskWarningFlowStage where riskWarning.id = ? and executionSequence > ? order by executionSequence asc", [riskWarning?.id, currentFlowStage?.executionSequence])
        if (verifyCondition['nextStage'])
        {
            def riskWarningStage = RiskWarningStage.find("from RiskWarningStage where code = '${verifyCondition['nextStage']}'")
            nextFlowStage = RiskWarningFlowStage.find("from RiskWarningFlowStage where riskWarning.id = ? and stage.id = ?", [riskWarning?.id, riskWarningStage?.id])
        }

        // 事件
        riskWarningFlowStageEventService.evaluate(currentFlowStage, "positive")

        if (!nextFlowStage)
        {
            map['flag'] = false
            map['message'] = "找不到工作流"
            return map
        }

        // 如果 nextFlowStage 为工作流的最后一个阶段，则将 nextFlowStage endTime 赋值成当前时间,将押品状态赋值成 Completed
        def lastFlowStage = RiskWarningFlowStage.find("from RiskWarningFlowStage where riskWarning.id = ? and executionSequence > ? order by executionSequence asc", [riskWarning?.id, nextFlowStage?.executionSequence])

        currentFlowStage.endTime = new Date()
        currentFlowStage.processed = true
        currentFlowStage.save flush: true

        nextFlowStage.startTime = new Date()
        if (!lastFlowStage)
        {
            nextFlowStage.endTime = new Date()
            // riskWarning.status = "Completed"
        }
        nextFlowStage.save flush: true

        riskWarning.stage = RiskWarningStage.find("from RiskWarningStage where id = ?", [nextFlowStage?.stage?.id])
        if (riskWarning?.stage?.code == "18")
        {
            riskWarning.actualEndTime = new Date()
        }
        riskWarning.save flush: true

        // 短信
        // riskWarningFlowStageNotificationService.sendNotification(riskWarning)

        map['flag'] = true
        map['message'] = "成功"
        return map
    }

    // 拒绝
    Boolean reject(RiskWarning riskWarning)
    {
        def flag = false
        def currentFlowStage = RiskWarningFlowStage.find("from RiskWarningFlowStage where riskWarning.id = ? and stage.id = ? order by executionSequence asc", [riskWarning?.id, riskWarning?.stage?.id])
        if (currentFlowStage?.canReject)
        {
            def previousFlowStage = RiskWarningFlowStage.find("from RiskWarningFlowStage where riskWarning.id = ? and executionSequence < ? and processed = true order by executionSequence desc", [riskWarning?.id, currentFlowStage?.executionSequence])
            if (previousFlowStage)
            {
                riskWarning.stage = RiskWarningStage.find("from RiskWarningStage where id = ?", [previousFlowStage?.stage?.id])
                if (riskWarning.validate())
                {
                    riskWarning.save flush: true

                    //发送消息
                    // riskWarningFlowStageNotificationService.sendNotification(riskWarning)

                    flag = true
                }
                else
                {
                    riskWarning.errors.each {
                        log.info "${it}"
                    }
                }
            }
        }
        flag
    }
}
